package cn.suzhang.jsharp.module.sys.service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import cn.suzhang.jsharp.common.dao.BaseDao;
import cn.suzhang.jsharp.common.service.BaseService;
import cn.suzhang.jsharp.module.sys.dao.UserDao;
import cn.suzhang.jsharp.module.sys.entity.SysRole;
import cn.suzhang.jsharp.module.sys.entity.SysUser;

/**
 * Service用于标注业务层组件
 * 
 * @author suzhang
 *
 */
@Service
public class UserService extends BaseService<SysUser, Long> {

    @Autowired
    private UserDao userDao;

    @Autowired
    private RoleService roleService;

    @Override
    public BaseDao<SysUser, Long> getBaseDao() {
        return userDao;
    }

    @Autowired
    @Qualifier("userJdbcTemplate")
    private JdbcTemplate userJdbcTemplate;

    @org.springframework.transaction.annotation.Transactional(value = "userTransactionManager")
    public void insert() {
        userJdbcTemplate.execute("insert into sys_user(password,sex,user_name) values('111',1,'wewew')");
        userJdbcTemplate.execute("insert into sys_user(password,sex,user_names) values('111',1,'wewew')");
        userJdbcTemplate.execute("insert into sys_user(password,sex,user_name) values('111',1,'wewew')");
    }

    public List<SysUser> getUsersByRepository() {
        return IterableUtils.toList(userDao.findAll());
    }

    public void insert(String name, Integer age) {
        userJdbcTemplate.update("insert into t_user(t_name,t_age)values(?,?)", name, age);
    }

    public SysUser findByUserName(String username) {
        return userDao.findByUserName(username);
    }

    public void grant(Long id, String[] roleIds) {
        SysUser user = this.find(id);
        SysRole role;
        Set<SysRole> roles = new HashSet<SysRole>();
        if (roleIds != null) {
            for (int i = 0; i < roleIds.length; i++) {
                Long rid = Long.parseLong(roleIds[i]);
                role = roleService.find(rid);
                roles.add(role);
            }
        }
        user.setRoles(roles);
        update(user);
    }

    public void saveOrUpdate(SysUser user) {
        if (user.getId() != null) {
            SysUser dbUser = find(user.getId());
            dbUser.setSex(user.getSex());
            update(dbUser);
        } else {
            save(user);
        }
    }

    public List<SysUser> findSearch(SysUser sysUser) {

        // Assert.notNull(model);

        List<SysUser> result = getBaseDao().findAll(new Specification<SysUser>() {
            @Override
            public Predicate toPredicate(Root<SysUser> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> list = new ArrayList<Predicate>();

                if (StringUtils.isNoneBlank(sysUser.getUserName())) {
                    list.add(cb.like(root.get("userName").as(String.class), "%" + sysUser.getUserName() + "%"));
                }

                if (sysUser.getSex() != null) {
                    list.add(cb.equal(root.get("sex").as(Integer.class), sysUser.getSex()));
                }

                Predicate[] p = new Predicate[list.size()];
                return cb.and(list.toArray(p));
            }
        });

        return result;
    }

}
